#include "uart_cli_simple_api.h"

#include "MQTTPacket.h"
#include "transport.h"
/*********************************************************************/
/***************************cli uart define***************************/
/*********************************************************************/

//用于创建任务
#ifndef MQTT_CLIENT_ENABLE
#define CLI_DEFAULT_UART_TASK_SIZE   0x600
#else
#define CLI_DEFAULT_UART_TASK_SIZE   0x3600 //mqtt需要的资源太大了
#endif

#define CLI_UART_TASK_PRIO           9
#define CLI_DEFAULT_PROC_TASK_SIZE   0xC00 /* 0x800:softap start would fail. */
#define CLI_PROC_TASK_PRIO           10
#define CLI_UART_SLEEP               1000

#if defined(UART_WAKE_UP_SAVE_CONFIG) && (UART_WAKE_UP_SAVE_CONFIG == 1)
#define CLI_WAIT_TIME 10000         /* wait 10 seconds */

#endif


/*********************************************************************/
/***************************cli uart params***************************/
/*********************************************************************/
const hi_uart_attribute g_cli_uart_cfg  = {115200, 8, 1, 0, 0};
uintptr_t g_cli_uart_baseaddr = HI_UART1_REG_BASE;
hi_u32 g_cli_event = 0;
hi_u16 g_cli_proc_task_size = CLI_DEFAULT_PROC_TASK_SIZE;
hi_u16 g_cli_uart_task_size = CLI_DEFAULT_UART_TASK_SIZE;
hi_bool g_cli_check_empty = HI_TRUE;
volatile hi_bool g_cli_have_uart_data;
hi_bool g_cli_init = HI_FALSE;
hi_u32 g_cli_uart_timer_handle;
const hi_u8 ch_test[] = "uart cli init test!";
hi_uart_idx g_cli_uart_port = HI_CLI_UART_PORT;


/*********************************************************************/
/*******************************function******************************/
/*********************************************************************/
hi_void hi_cli_set_check_uart_busy(hi_bool enable)
{
    g_cli_check_empty = enable;
}

hi_void timer_handle(hi_u32 data)
{
    hi_unref_param(data);
    g_cli_have_uart_data = HI_FALSE;
}

BSP_RAM_TEXT_SECTION hi_u32 lp_cli_uart_vote(hi_void)
{
    hi_bool val;

    if (g_cli_check_empty) {
        if (g_cli_have_uart_data) {
            return HI_NO_SLEEP;
        }
        hi_u32 ret = hi_uart_is_busy(g_cli_uart_port, &val);
        if ((ret == HI_ERR_SUCCESS) && (val == HI_TRUE)) {
            return HI_NO_SLEEP;
        }
        val = HI_FALSE;
        ret = hi_uart_is_buf_empty(g_cli_uart_port, &val);
        if (ret == HI_ERR_SUCCESS && val == HI_FALSE) {
            return HI_NO_SLEEP;
        }
    }
    return HI_DEEP_SLEEP;
}
/**
 * @brief 初始化cli串口，用于接收串口指令
 * 参考格式来源：at_uart_init()
*/
hi_u32 cli_uart_init(hi_void)
{
    hi_u32 ret;

    (hi_void)hi_uart_deinit(g_cli_uart_port);
    ret = hi_uart_init(g_cli_uart_port, &g_cli_uart_cfg, HI_NULL);
    if (ret != HI_ERR_SUCCESS) {
        return HI_ERR_FAILURE;
    }

    if (g_cli_uart_port == HI_UART_IDX_0) 
    {
        g_cli_uart_baseaddr = HI_UART0_REG_BASE;
    } 
    else if (g_cli_uart_port == HI_UART_IDX_1) 
    {
        g_cli_uart_baseaddr = HI_UART1_REG_BASE;
    } 
    else if (g_cli_uart_port == HI_UART_IDX_2) 
    {
        g_cli_uart_baseaddr = HI_UART2_REG_BASE;
    }

    return HI_ERR_SUCCESS;
}

hi_void *cli_proc_task_body(hi_void* param)
{
    hi_unref_param(param);
    cli_printf("cli_proc_task_body task run normal!");
    for (;;) {
        (hi_void)hi_sleep(CLI_UART_SLEEP);
    }
}


hi_void *cli_uart_task_body(hi_void* param)
{
    hi_unref_param(param);
    cli_printf("cli_uart_task_body task run normal!");
    hi_char ch;
    hi_u8 cmd_ch;
    hi_s32 n;

    for (;;) 
    {
        n = hi_uart_read(g_cli_uart_port, (hi_u8 *)&ch, 1);
        if (n != 1) {
            (hi_void)hi_sleep(CLI_UART_SLEEP);
            continue;
        }
        else
        {
          //用于测试
          //hi_uart_write(g_cli_uart_port,  (hi_u8 *)&ch, 1);
          cmd_ch = ch;
          uart_cmd_task_scheduling(cmd_ch);
        }
        #if defined(UART_WAKE_UP_SAVE_CONFIG) && (UART_WAKE_UP_SAVE_CONFIG)
        if ((hi_lpc_get_type() != HI_NO_SLEEP) && (g_cli_check_empty == HI_TRUE)) {
            g_cli_have_uart_data = HI_TRUE;
            hi_timer_start(g_cli_uart_timer_handle, HI_TIMER_TYPE_ONCE, CLI_WAIT_TIME, timer_handle, 0);
        }
        #endif
    }
}

/**
 * @brief 用于创建simple cli uart任务，
 * 接收指令、解析指令并调用相关函数执行
 * @see hi_at_init 作为格式参考
*/
hi_u32 cli_uart_init_task(hi_void)
{
    hi_u32 ret;
    hi_u32 cli_uart_task, cli_proc_task;

    if (g_cli_init == HI_TRUE) {
        return HI_ERR_SUCCESS;
    }

    //初始化串口，默认为UART0
    ret = cli_uart_init();
    if (ret != HI_ERR_SUCCESS) {
        cli_printf("An error occurred at cli_uart_init!");
        return ret;
    }
    else
    {
        hi_uart_write(g_cli_uart_port, ch_test, 20);
    }

    //创建cli事件，获取cli事件使用ID
    hi_event_create(&g_cli_event);
    hi_task_attr attr = {0};

    //创建cli 功能函数任务
    attr.stack_size = g_cli_proc_task_size;
    attr.task_prio = CLI_PROC_TASK_PRIO;    
    attr.task_name = (void*)"cli_proc";
    ret = hi_task_create(&cli_proc_task, &attr, cli_proc_task_body, 0);
    APP_ERR_CHECK(ret);

    //创建串口收发与指令解析任务
    attr.stack_size = g_cli_uart_task_size;
    attr.task_prio = CLI_UART_TASK_PRIO;    
    attr.task_name = (void*)"cli_uart";
    ret = hi_task_create(&cli_uart_task, &attr, cli_uart_task_body, 0);
    APP_ERR_CHECK(ret);
    #if defined(UART_WAKE_UP_SAVE_CONFIG) && (UART_WAKE_UP_SAVE_CONFIG == 1)
    hi_timer_create(&g_cli_uart_timer_handle);
    hi_lpc_register_check_handler((hi_u32_void_callback) lp_cli_uart_vote);
    #endif
    g_cli_init = HI_TRUE;

    return ret;
}

hi_u32 uart_cli_config_before_sleep(hi_void)
{
    /* 用户根据实际io设计配置，防止深睡阶段漏电流 */
    if (hi_lpc_get_type() == HI_DEEP_SLEEP) {
        /* 用户根据实际io使用情况设置:无上拉电阻、无下拉电阻、禁止输入信号使能等，防止漏电流，具体参考芯片手册 */
        /*
        hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_6), g_iocfg_backup.gpio6_cfg);
        hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_8), g_iocfg_backup.gpio8_cfg);
        hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_10), g_iocfg_backup.gpio10_cfg);
        hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_11), g_iocfg_backup.gpio11_cfg);
        hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_12), g_iocfg_backup.gpio12_cfg);
        hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_13), g_iocfg_backup.gpio13_cfg);
        hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_SFC_CSN), g_iocfg_backup.sfc_csn_cfg);

        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_6), IOCFG_LOWPOWER_CFG_VAL);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_8), IOCFG_LOWPOWER_CFG_VAL);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_10), IOCFG_LOWPOWER_CFG_VAL);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_11), IOCFG_LOWPOWER_CFG_VAL);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_12), IOCFG_LOWPOWER_CFG_VAL);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_13), IOCFG_LOWPOWER_CFG_VAL);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_SFC_CSN), IOCFG_LOWPOWER_CFG_VAL);
        */
        hi_uart_lp_save(HI_UART_IDX_0);
        hi_uart_lp_save(HI_UART_IDX_1);
        hi_uart_lp_save(HI_UART_IDX_2);
    }
    return HI_ERR_SUCCESS;
}

hi_u32 uart_cli_config_after_sleep(hi_void)
{
    /* 用户根据实际io设计恢复，防止深睡阶段漏电流 */
    if (hi_lpc_get_type() == HI_DEEP_SLEEP) {
        /* 用户根据实际io使用情况配置恢复 */
        /*
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_6), g_iocfg_backup.gpio6_cfg);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_8), g_iocfg_backup.gpio8_cfg);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_10), g_iocfg_backup.gpio10_cfg);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_11), g_iocfg_backup.gpio11_cfg);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_12), g_iocfg_backup.gpio12_cfg);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_13), g_iocfg_backup.gpio13_cfg);
        hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_SFC_CSN), g_iocfg_backup.sfc_csn_cfg);
        */
    }
    return HI_ERR_SUCCESS;
}

//用于运行SYS_RUN
void cli_uart_main(void)
{
    #if defined(UART_WAKE_UP_SAVE_CONFIG) && (UART_WAKE_UP_SAVE_CONFIG == 1)
    hi_lpc_init();
    hi_lpc_register_hw_handler(uart_cli_config_before_sleep, uart_cli_config_after_sleep);
    #endif
    cli_uart_init_task();
}

SYS_RUN(cli_uart_main);

